parser grammar AnalisisParser;

options {

  language = Java;
  tokenVocab = AnalisisLexer;
}

@header{
  package practicaspl.ocho;
  import java.util.Hashtable;
}

@members{
  Hashtable tablavar = new Hashtable();
  
  private ArrayList<RecognitionException> errors = new ArrayList<RecognitionException>();
  public ArrayList<RecognitionException> getErrors() {
    return errors;
  }
  @Override
  public void reportError (RecognitionException e) {
     String msg = getErrorMessage(e, getTokenNames());
     System.err.println(msg);
     errors.add(e);
  }
  
  int tabulador = 3;
  
  String tabular( int tabulador){
  String tab = "";
    for(int i = 0; i <= tabulador; i++)
    {
        tab += " ";
    }
    return tab;
  }
}



entrada : (instruccion)* EOF;

instruccion 
: e=expr SEMICOLON {System.out.println("Expresion: "+e);}
| i=asig SEMICOLON {System.out.println("Asignacion: "+i);}
;

asig returns [int valor = 0]
 : i=IDENT IGUAL e=expr {valor = e;}
  {tablavar.put($i.text, new Integer(e));}
;

expr returns [int res=0] 
: e1=exp_mult {res=e1;}
((MAS e2=exp_mult {res += e2;})
|(MENOS e2=exp_mult {res -= e2;}))*
;
exp_mult returns [int res=0] 
: e1=exp_base { res= e1;}
((MULT e2=exp_base {res = res * e2;})
|(DIV e2=exp_base {res= res/e2;}))*;
  catch [ArithmeticException ae]{
    System.err.println("Error , estamos intentando dividir entre 0");
    throw ae;
  }
exp_base returns [int res=0] 
: n=NUMERO {res = new Integer(n.getText()).intValue();}
|IDENT 
    {
        Integer v = (Integer)tablavar.get($IDENT.text);
        if ( v!=null ){ $res = v.intValue();}
        else { {tablavar.put($IDENT.text, new Integer(0)); } 
          $res = (Integer)tablavar.get($IDENT.text); 
        }
       }
| PARENTA e=expr PARENTC
{res = e;}
;


codigoC : (ifC[false]|whileC[false])*;
  

ifC [boolean estawhi]:
 IF PARENTA (IDENT|LETRA) PARENTC LLAVEA (combreak[estawhi]) SEMICOLON LLAVEC;

whileC [boolean estawhi] :
 WHILE{estawhi = true;} PARENTA (IDENT|LETRA) PARENTC LLAVEA (ifC [estawhi])* LLAVEC {estawhi = false;};

combreak [boolean estawhi] : BREAK {if(estawhi == true){
  System.out.println("EL break se encuentra en un bucle while");}
  else
  {System.out.println("EL break  NO se encuentra en un bucle while");} };
  
  
  
reglas returns[String cad = ""]:
    v=VOID i=IDENT pa=PARENTA v1=VOID pc=PARENTC lla=LLAVEA
   {cad += $v.text + $i.text + $pa.text + $v1.text + $pc.text + $lla.text + "\n"+ tabular(tabulador);} d=declaracion si=sentif llc=LLAVEC { cad += d + si + $llc.text;}
   { System.out.println("Fomateado : ");
      System.out.println(cad);};

sentif returns [String sif = ""]: 
i=IF pa=PARENTA comp=comparacion pc=PARENTC lla=LLAVEA
{sif += $i.text + $pa.text + comp + $pc.text + $lla.text + "\n" + tabular(tabulador);}
llc=LLAVEC {sif += $llc.text + "\n";};


comparacion returns [String comp = ""]:
  n=NUMERO m=MULT i=LETRA (c=MM|c=CETIQUETA|c=AETIQ_O) (s=LETRA|s=NUMERO)
{comp += $n.text + $m.text + $i.text + $c.text + $s.text;};  
       
declaracion returns [String dec = ""]:
i=INT id=LETRA{dec += $i.text + $id.text;}  aux=auxiliar s=SEMICOLON {dec+= aux + $s.text + "\n" + tabular(tabulador) ;} ;

auxiliar returns [String aux = ""]:
  (c=COMA d=LETRA{aux += $c.text + $d.text;})+;




entradaxml: etiquetas+;

etiquetas : AETIQ_O i=IDENT  CETIQUETA aux2 AETIQ_C i1=IDENT{if(!$i.text.equals($i1.text)) System.out.println("Las estiquetas no son iguales");} CETIQUETA;

aux2 : (STRING|etiquetas*);

